﻿using log4net;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using suirui.ZhuMu.Common;
using suirui.ZhuMu.Middlewares;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace suirui.ZhuMu.Framework
{
    public static class JWTAuthenticationSetup
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(GlobalExceptionMildd));

        public static void AddJWTAuthenticationSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));

            var ValidAudience = AppConfigration.Configuration["audience"];
            var ValidIssuer = AppConfigration.Configuration["issuer"];
            var SecurityKey = AppConfigration.Configuration["SecurityKey"];
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })  //默认授权机制名称；                                      
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,//是否验证Issuer
                    ValidateAudience = true,//是否验证Audience
                    ValidateLifetime = true,//是否验证失效时间 //是否验证超时  当设置exp和nbf时有效 同时启用ClockSkew 
                    ValidateIssuerSigningKey = true,//是否验证SecurityKey
                    ValidAudience = ValidAudience,//Audience
                    ValidIssuer = ValidIssuer,//Issuer，这两项和前面签发jwt的设置一致  表示谁签发的Token
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey)),//拿到SecurityKey
                    //注意这是缓冲过期时间，总的有效时间等于这个时间加上jwt的过期时间，如果不配置，默认是5分钟
                    ClockSkew = TimeSpan.Zero,// TimeSpan.FromSeconds(1),
                    AudienceValidator = (m, n, z) =>
                    {
                        return m != null && m.FirstOrDefault().Equals(AppConfigration.Configuration["audience"]);
                    },//自定义校验规则，可以新登录后将之前的无效 
                };
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        //Token expired
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }
                        return Task.CompletedTask;
                    }
                };
                options.SaveToken = true;
                options.RequireHttpsMetadata = false;
            });
        }
    }
}
